package com.anywhere.freightman.config;

import com.anywhere.freightman.car.model.DriverModel;
import com.anywhere.freightman.car.service.IDriverService;
import com.anywhere.freightman.common.ContextKeys;
import com.anywhere.freightman.common.annotation.Permission;
import com.anywhere.freightman.common.entity.car.DriverEntity;
import com.anywhere.freightman.common.entity.user.Account;
import com.anywhere.freightman.common.enumeration.TokenType;
import com.anywhere.freightman.common.ex.ForbiddenException;
import com.anywhere.freightman.system.model.AccessToken;
import com.anywhere.freightman.system.model.Resource;
import com.anywhere.freightman.system.service.IAccessTokenService;
import com.anywhere.freightman.system.service.IUserService;
import com.google.common.base.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

@Component
public class FilterInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private IUserService userService;
    @Autowired
    private IAccessTokenService accessTokenService;
    @Autowired
    private IDriverService driverService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取controller的权限注解
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        Permission permission = method.getAnnotation(Permission.class);

        if (permission == null || !permission.isAuth()) {
            return true;
        }

        String token = request.getHeader(ContextKeys.TOKEN_KEY);
        if (Strings.isNullOrEmpty(token)) {
            throw new ForbiddenException();
        }

        AccessToken accessToken = accessTokenService.getByToken(token);

        if (accessToken == null) {
            throw new ForbiddenException();
        }


        // 读取token对应的权限粒子
        Set<Resource> resources = new HashSet<>();
        if (accessToken.getType().equals(TokenType.USER)) {
            resources = userService.getResources(accessToken.getUserId());
        } else {
            Resource res = new Resource();
            res.setCode("APP_DRIVER");
            resources.add(res);
        }


        boolean isAuth = false;

        for (Resource item : resources) {
            if (item.getCode().equals(permission.code())) {
                isAuth = true;
                break;
            }
        }

        if (!isAuth) {
            throw new ForbiddenException();
        }

        if (accessToken.getType().equals(TokenType.USER)) {
            Account account = userService.selectByToken(token);
            account.setResources(resources);
            request.setAttribute(ContextKeys.REQUEST_ACCOUNT, account);
        } else {
            DriverModel model = driverService.getById(accessToken.getUserId());
            DriverEntity entity = new DriverEntity();
            BeanUtils.copyProperties(model, entity);
            request.setAttribute(ContextKeys.REQUEST_ACCOUNT, entity);
        }


        return true;
    }
}
